package com.weilx959.spt.core.component;

import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.validation.base.ValidatorBase;
import com.weilx959.spt.core.utils.FXMLUtil;
import com.weilx959.spt.core.utils.Try;
import javafx.beans.DefaultProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Objects;

/**
 * ComboBox表单项控件
 *
 * @param <T> ComboBox的泛型
 * @author weilx
 * @since 2024-5-29
 */
@Slf4j
@DefaultProperty("items")
public class ComboBoxFormItemControl<T> extends ValidatorFormItemControl<T> {
    private static final String XML = "/assets/fxml/component/combo-box-form-control.fxml";

    private ObjectProperty<ObservableList<T>> items;

    @FXML
    private Label labelControl;

    @FXML
    @Getter
    private JFXComboBox<T> valueControl;

    public ComboBoxFormItemControl() {
        super();
        initialize();
    }

    @Override
    public Try<String> validate() {
        return Try.of(() -> {
            if (!valueControl.validate()) {
                throw new IllegalStateException(valueControl.getActiveValidator().getMessage());
            }
        });
    }

    @Override
    public void addValidator(ValidatorBase... validators) {
        valueControl.setValidators(validators);
    }

    public EventHandler<ActionEvent> getOnAction() {
        return valueControl.getOnAction();
    }

    public void setOnAction(EventHandler<ActionEvent> onAction) {
        valueControl.setOnAction(onAction);
    }

    public ObservableList<T> getItems() {
        return items.get();
    }

    public ObjectProperty<ObservableList<T>> itemsProperty() {
        if (Objects.isNull(items)) {
            items = new SimpleObjectProperty<>(this, "ITEMS", FXCollections.observableArrayList());
        }
        return items;
    }

    public void setItems(ObservableList<T> items) {
        itemsProperty().set(items);
    }

    private void initialize() {
        // load
        FXMLUtil.loadControl(this, XML);
        // 选择框
        valueControl.itemsProperty().bindBidirectional(itemsProperty());
        valueControl.valueProperty().bindBidirectional(valueProperty());
    }

    // builder
    public static <T> ComboBoxFormItemControlBuilder<T> builder() {
        return new ComboBoxFormItemControlBuilder<>();
    }

    public static class ComboBoxFormItemControlBuilder<T>
        extends ValidatorFormItemControlBuilder<T, ComboBoxFormItemControl<T>, ComboBoxFormItemControlBuilder<T>> {
        private ObservableList<T> items;

        public ComboBoxFormItemControlBuilder<T> items(ObservableList<T> items) {
            this.items = items;
            return this;
        }

        public ComboBoxFormItemControlBuilder<T> item(T item) {
            if (CollectionUtils.isEmpty(items)) {
                items = FXCollections.observableArrayList();
            }
            items.add(item);
            return this;
        }

        @Override
        public ComboBoxFormItemControl<T> build() {
            ComboBoxFormItemControl<T> control = super.build();

            if (CollectionUtils.isNotEmpty(items)) {
                control.setItems(items);
            }
            return control;
        }

        @Override
        protected ComboBoxFormItemControl<T> newFormItemControl() {
            return new ComboBoxFormItemControl<>();
        }

        @Override
        protected ComboBoxFormItemControlBuilder<T> self() {
            return this;
        }
    }
}
